package com.gz.logistics.util;

import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import android.util.SparseArray;

/**
 *	可根据观测者类型通知不同观测者更新数据
 *  @author 陈希然
 */
public class ObserverWorker {

	private static Lock mLock;
	private static ObserverWorker mInstance;
	private SparseArray<MessageObservable> mObservables;//被观测者; 可能会有私信、聊天室或者消息列表等其他..

	static{
		mLock = new ReentrantLock();
	}
	
	private ObserverWorker() {
		// TODO Auto-generated constructor stub
		mObservables = new SparseArray<MessageObservable>();
	}
	
	public static ObserverWorker getInstance() {    	
    	return mInstance;
	}
	
	public static void init() {
		if(mInstance == null){
    		mLock.lock();
    		try{
				if(mInstance == null){
					mInstance = new ObserverWorker();
				}
    		}finally{
    			mLock.unlock();
    		}
    	}
	}
	
	/**
	 * 根据观测者type通知对应的观测者
	 * @param type 观测者类型
	 */
	public void dispatchMessage(int type) {
		MessageObservable observable = mObservables.get(type);
		if(observable != null) {
			ObserverMessage<Object> msg = new ObserverMessage<Object>();
			msg.data = null;
			msg.type = type;
			observable.notifyDataSetChange(msg);
		}
	}
	
	/**
	 * 根据参数观测者type通知对应的观测者
	 * @param type 观测者类型
	 * @param message 携带的数据
	 */
	public <T> void dispatchMessage(int type, T message) {
		MessageObservable observable = mObservables.get(type);
		if(observable != null) {
			ObserverMessage<T> msg = new ObserverMessage<T>();
			msg.data = message;
			msg.type = type;
			observable.notifyDataSetChange(msg);
		}
	}
	
	
	public void registerObserver(int type, Observer observer) {
		MessageObservable observable = mObservables.get(type);
		if(observable == null) {
			observable = new MessageObservable();
			mObservables.append(type, observable);
		}
		observable.addObserver(observer);
	}
	
	public void unRegisterObserver(int type, Observer observer) {
		MessageObservable observable = mObservables.get(type);
		if(observable != null) {
			observable.deleteObserver(observer);
			mObservables.delete(type);
		}
	}
	
	static class MessageObservable extends Observable {
		
		public void notifyDataSetChange(Object data) {
			setChanged();
			notifyObservers(data);
		}
	}

	public static class ObserverMessage<T> {
		public int type;
		public T data;
	}
}
